package cn.rubintry.calculator

import android.widget.TextView
import java.math.BigDecimal


class IntegerCalculator() : BaseCalculator<Int>(), ICalculator<Int> {

    override fun forcePositive(): IntegerCalculator {
        forcePositive = true
        return this
    }

    override fun add(other: Any?): ICalculator<Int> {
        checkResultNotNull()
        when(other){
            is IntegerModule -> {
                resultModule?.add(other)
            }

            is TextView -> {
                resultModule?.add(IntegerModule(other))
            }

            is String? -> {
                resultModule?.add(IntegerModule(other ?: "0"))
            }

            is Int -> {
                resultModule?.add(IntegerModule(other.toString()))
            }

            is Double -> {
                resultModule?.add(IntegerModule(other.toInt().toString()))
            }

            is BigDecimal -> {
                resultModule?.add(IntegerModule(other.toInt().toString()))
            }
        }
        return this
    }

    override fun subtract(other: Any?): IntegerCalculator {
        checkResultNotNull()
        when(other){
            is IntegerModule -> {
                resultModule?.subtract(other)
            }

            is TextView -> {
                resultModule?.subtract(IntegerModule(other))
            }

            is String? -> {
                resultModule?.subtract(IntegerModule(other ?: "0"))
            }

            is Int -> {
                resultModule?.subtract(IntegerModule(other.toString()))
            }

            is Double -> {
                resultModule?.subtract(IntegerModule(other.toInt().toString()))
            }

            is BigDecimal -> {
                resultModule?.subtract(IntegerModule(other.toInt().toString()))
            }
        }
        return this
    }

    override fun multiply(other: Any?, scale: Int): ICalculator<Int> {
        checkResultNotNull()
        when(other){
            is IntegerModule -> {
                resultModule?.multiply(other , scale)
            }

            is TextView -> {
                resultModule?.multiply(IntegerModule(other) , scale)
            }

            is String? -> {
                resultModule?.multiply(IntegerModule(other ?: "0") , scale)
            }

            is Int -> {
                resultModule?.multiply(IntegerModule(other.toString()) , scale)
            }

            is Double -> {
                resultModule?.multiply(IntegerModule(other.toInt().toString()))
            }

            is BigDecimal -> {
                resultModule?.multiply(IntegerModule(other.toInt().toString()))
            }
        }
        return this
    }


    override fun divide(other: Any?, scale: Int): IntegerCalculator {
        checkResultNotNull()
        when(other){
            is IntegerModule -> {
                resultModule?.divide(other , scale)
            }

            is TextView -> {
                resultModule?.divide(IntegerModule(other) , scale)
            }

            is String? -> {
                resultModule?.divide(IntegerModule(other ?: "0") , scale)
            }

            is Int -> {
                resultModule?.divide(IntegerModule(other.toString()) , scale)
            }

            is Double -> {
                resultModule?.divide(IntegerModule(other.toInt().toString()))
            }

            is BigDecimal -> {
                resultModule?.divide(IntegerModule(other.toInt().toString()))
            }
        }
        return this
    }

    override fun appendUnit(unit: String): IntegerCalculator {
        checkResultNotNull()
        resultModule?.appendUnit(unit)
        return this
    }


    override fun into(vararg target: TextView?) {
        assert(resultModule != null){"请先调用加减乘除方法"}
        for (textView in target) {
            textView?.text = resultModule?.getNumberFromView()
        }
    }

    override fun toString(): String {
        return resultModule.toString()
    }


    override fun copy(): IntegerCalculator {
        val instance = this.javaClass.newInstance()
        copyFields(this.javaClass , instance)
        return instance
    }

    private fun copyFields(clazz: Class<*>?, instance: IntegerCalculator) {
        val declaredFields = clazz?.declaredFields
        declaredFields?.let {
            for (declaredField in it) {
                declaredField.isAccessible = true
                declaredField.set(instance , declaredField.get(this))
            }
        }

        if(null != clazz?.superclass){
            copyFields(clazz.superclass , instance)
        }
    }

}